ASSERT( !(old_sl2e & _PAGE_PRESENT) );
#endif
- get_shadow_ref(sl1mfn);
+ if (!get_shadow_ref(sl1mfn))
+ BUG();
l2pde_general(d, &gl2e, &sl2e, sl1mfn);
__guest_set_l2e(ed, va, gl2e);
__shadow_set_l2e(ed, va, sl2e);
for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
{
- l1pte_propagate_from_guest(d, gpl1e[i], &spl1e[i]);
- if ( spl1e[i] & _PAGE_PRESENT )
- shadow_get_page_from_l1e(mk_l1_pgentry(spl1e[i]), d);
+ unsigned long sl1e;
+
+ l1pte_propagate_from_guest(d, gpl1e[i], &sl1e);
+ if ( (sl1e & _PAGE_PRESENT) &&
+ !shadow_get_page_from_l1e(mk_l1_pgentry(sl1e), d) )
+ sl1e = 0;
+ spl1e[i] = sl1e;
}
}
}
unsigned long old = pt[i];
unsigned long new = old & ~_PAGE_RW;
- if ( is_l1_shadow )
- shadow_get_page_from_l1e(mk_l1_pgentry(new), d);
+ if ( is_l1_shadow &&
+ !shadow_get_page_from_l1e(mk_l1_pgentry(new), d) )
+ BUG();
count++;
pt[i] = new;
unsigned long opte = *ppte;
unsigned long npte = opte & ~_PAGE_RW;
- if ( npte & _PAGE_PRESENT)
- shadow_get_page_from_l1e(mk_l1_pgentry(npte), d);
+ if ( (npte & _PAGE_PRESENT) &&
+ !shadow_get_page_from_l1e(mk_l1_pgentry(npte), d) )
+ BUG();
*ppte = npte;
put_page_from_l1e(mk_l1_pgentry(opte), d);
(d != owner) )
{
res = get_page_from_l1e(l1e, owner);
- printk("tried to map page from domain %d into shadow page tables "
+ printk("tried to map mfn %p from domain %d into shadow page tables "
"of domain %d; %s\n",
- owner->id, d->id, res ? "success" : "failed");
+ mfn, owner->id, d->id, res ? "success" : "failed");
}
if ( unlikely(!res) )
+ {
perfc_incrc(shadow_get_page_fail);
+ FSH_LOG("%s failed to get ref l1e=%p\n", l1_pgentry_val(l1e));
+ }
return res;
}
//
if ( (old_hl2e ^ new_hl2e) & (PAGE_MASK | _PAGE_PRESENT) )
{
- if ( new_hl2e & _PAGE_PRESENT )
- shadow_get_page_from_l1e(mk_l1_pgentry(new_hl2e), ed->domain);
+ if ( (new_hl2e & _PAGE_PRESENT) &&
+ !shadow_get_page_from_l1e(mk_l1_pgentry(new_hl2e), ed->domain) )
+ new_hl2e = 0;
if ( old_hl2e & _PAGE_PRESENT )
put_page_from_l1e(mk_l1_pgentry(old_hl2e), ed->domain);
}
static inline void l1pte_propagate_from_guest(
struct domain *d, unsigned long gpte, unsigned long *spte_p)
{
- unsigned long spte = *spte_p;
unsigned long pfn = gpte >> PAGE_SHIFT;
unsigned long mfn = __gpfn_to_mfn(d, pfn);
+ unsigned long spte;
#if SHADOW_VERBOSE_DEBUG
- unsigned long old_spte = spte;
+ unsigned long old_spte = *spte_p;
#endif
- if ( unlikely(!mfn) )
- {
- // likely an MMIO address space mapping...
- //
- *spte_p = 0;
- return;
- }
-
spte = 0;
- if ( (gpte & (_PAGE_PRESENT|_PAGE_ACCESSED) ) ==
- (_PAGE_PRESENT|_PAGE_ACCESSED) ) {
-
+
+ if ( mfn &&
+ ((gpte & (_PAGE_PRESENT|_PAGE_ACCESSED) ) ==
+ (_PAGE_PRESENT|_PAGE_ACCESSED)) ) {
+
spte = (mfn << PAGE_SHIFT) | (gpte & ~PAGE_MASK);
if ( shadow_mode_log_dirty(d) ||
#if SHADOW_VERBOSE_DEBUG
if ( old_spte || spte || gpte )
- debugtrace_printk("l1pte_propagate_from_guest: gpte=0x%p, old spte=0x%p, new spte=0x%p\n", gpte, old_spte, spte);
+ SH_VLOG("l1pte_propagate_from_guest: gpte=0x%p, old spte=0x%p, new spte=0x%p", gpte, old_spte, spte);
#endif
*spte_p = spte;
#endif
old_spte = *shadow_pte_p;
- l1pte_propagate_from_guest(d, new_pte, shadow_pte_p);
- new_spte = *shadow_pte_p;
+ l1pte_propagate_from_guest(d, new_pte, &new_spte);
// only do the ref counting if something important changed.
//
{
perfc_incrc(validate_pte_changes);
- if ( new_spte & _PAGE_PRESENT )
- shadow_get_page_from_l1e(mk_l1_pgentry(new_spte), d);
+ if ( (new_spte & _PAGE_PRESENT) &&
+ !shadow_get_page_from_l1e(mk_l1_pgentry(new_spte), d) )
+ new_spte = 0;
if ( old_spte & _PAGE_PRESENT )
put_page_from_l1e(mk_l1_pgentry(old_spte), d);
}
+ *shadow_pte_p = new_spte;
+
// paranoia rules!
return 1;
}
unsigned long new_pde,
unsigned long *shadow_pde_p)
{
- unsigned long old_spde = *shadow_pde_p;
- unsigned long new_spde;
+ unsigned long old_spde, new_spde;
perfc_incrc(validate_pde_calls);
- l2pde_propagate_from_guest(d, &new_pde, shadow_pde_p);
- new_spde = *shadow_pde_p;
+ old_spde = *shadow_pde_p;
+ l2pde_propagate_from_guest(d, &new_pde, &new_spde);
+
+ // XXX Shouldn't we supposed to propagate the new_pde to the guest?
// only do the ref counting if something important changed.
//
{
perfc_incrc(validate_pde_changes);
- if ( new_spde & _PAGE_PRESENT )
- get_shadow_ref(new_spde >> PAGE_SHIFT);
+ if ( (new_spde & _PAGE_PRESENT) &&
+ !get_shadow_ref(new_spde >> PAGE_SHIFT) )
+ BUG();
if ( old_spde & _PAGE_PRESENT )
put_shadow_ref(old_spde >> PAGE_SHIFT);
}
+ *shadow_pde_p = new_spde;
+
// paranoia rules!
return 1;
}
if ( sl1mfn )
{
perfc_incrc(shadow_set_l1e_unlinked);
- get_shadow_ref(sl1mfn);
+ if (!get_shadow_ref(sl1mfn))
+ BUG();
l2pde_general(d, &gpde, &sl2e, sl1mfn);
__guest_set_l2e(ed, va, gpde);
__shadow_set_l2e(ed, va, sl2e);
}
old_spte = l1_pgentry_val(shadow_linear_pg_table[l1_linear_offset(va)]);
- shadow_linear_pg_table[l1_linear_offset(va)] = mk_l1_pgentry(new_spte);
// only do the ref counting if something important changed.
//
if ( (old_spte ^ new_spte) & (PAGE_MASK | _PAGE_RW | _PAGE_PRESENT) )
{
- if ( new_spte & _PAGE_PRESENT )
- shadow_get_page_from_l1e(mk_l1_pgentry(new_spte), d);
+ if ( (new_spte & _PAGE_PRESENT) &&
+ !shadow_get_page_from_l1e(mk_l1_pgentry(new_spte), d) )
+ new_spte = 0;
if ( old_spte & _PAGE_PRESENT )
put_page_from_l1e(mk_l1_pgentry(old_spte), d);
}
+
+ shadow_linear_pg_table[l1_linear_offset(va)] = mk_l1_pgentry(new_spte);
}
/************************************************************************/